﻿/***************************************************************
 * Name:      task.cpp
 * Purpose:   单个下载任务类
 * Author:    杨卓荦 (yzl@bang5.net)
 * Created:   2010-08-29
 * Copyright: 杨卓荦 (http://www.bang5.net)
 * License:
 **************************************************************/

#include "task.h"
#include <wx/msgdlg.h>
using namespace std;
// 构造函数
Task::Task(const wxString& full_url,
           const string& local_file_name,
           const int threads) :
  http_info_(full_url) {
#if defined(__WXMSW__)
  const char kFileSeparator = '\\';
#else
  const char kFileSeparator = '/';
#endif
  if (http_info_.GetInfo()) {
    local_file_name_ = local_file_name;
    if (local_file_name_[local_file_name_.size() - 1] != kFileSeparator) {
      local_file_name_ += kFileSeparator;
    }
    local_file_name_ += http_info_.GetFileName();
    if (local_file_name_[local_file_name_.size() - 1] == kFileSeparator) {
      local_file_name_ += "index.htm";
    }
    long long int file_size = http_info_.GetFileSize();  // 文件总大小
    long long int block_size = file_size / threads + 1;  // 每个块大小
    long long int start_pos = 0;  // 初始位置
    long long int end_pos = block_size;  // 结束位置
    for (int i = 0; i < threads; ++i) {
      HttpWorker* http_worker = new HttpWorker(http_info_.GetFullURL(),
          100,  // 重复100次
          1,  // 重复等待1秒
          start_pos,  // 从0字节开始
          end_pos,
          http_info_.GetReferer(),
          local_file_name_);
      http_worker->Create();
      http_worker->Run();
      http_workers_.push_back(http_worker);
      start_pos += block_size;
      end_pos += block_size;
      if (end_pos > file_size) end_pos = file_size;
    }
  } else {
    // HTTP 信息获取失败
    wxMessageBox(_("HTTP信息获取失败"));
  }
}

// 析构函数
Task::~Task() {
  while (http_workers_.size() > 0) {
    HttpWorker* http_worker = http_workers_.back();
    if (NULL != http_worker) delete http_worker;
    http_workers_.pop_back();
  }
}

void Task::GetFileName(string& file_name) const {
  size_t pos = local_file_name_.find_last_of("/\\");
  file_name = local_file_name_.substr(pos + 1);
}

size_t Task::GetWorkerCount() const {
  return http_workers_.size();
}

long long int Task::GetFileSize() const {
  return http_info_.GetFileSize();
}

long long int Task::GetTotalByte() {
  long long int total_byte = 0;
  for (list<HttpWorker*>::iterator i = http_workers_.begin(); i != http_workers_.end(); ++i) {
    if (NULL != *i) {
      total_byte += (*i)->GetTotalByte();
    }
  }
  return total_byte;
}

void Task::GetFilePathAndName(string& file_path) const {
  file_path = local_file_name_;
}

void Task::GetFullURL(string& full_url) const {
  full_url = http_info_.GetFullURL();
}

void Task::GetReferer(string& referer) const {
  referer = http_info_.GetReferer();
}
